package vin.pth.authorization.provider;

import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import vin.pth.authorization.enums.AuthorizationErrorCode;
import vin.pth.authorization.exception.AuthorizationException;
import vin.pth.authorization.token.UsernamePasswordToken;
import vin.pth.base.pojo.Authentication;
import vin.pth.base.pojo.UserDetails;
import vin.pth.base.service.UserDetailsService;

/**
 * 用户名密码提供者.
 *
 * @author cocoon
 */
@RequiredArgsConstructor
@Component
public class UsernamePasswordProvider implements AuthorizationProvider {

  private final static String USERNAME_KEY = "username";
  private final static String PASSWORD_KEY = "password";

  private final PasswordEncoder passwordEncoderService;
  private final UserDetailsService userDetailsService;

  @Override
  public Authentication authenticate(Map<String, Object> param) throws AuthorizationException {
    String username = param.get(USERNAME_KEY) + "";
    String password = param.get(PASSWORD_KEY) + "";
    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
    if (userDetails == null) {
      throw new AuthorizationException(AuthorizationErrorCode.AUTHENTICATION_FAILED,
          "用户名或者密码错误");
    }
    if (passwordEncoderService.matches(password, userDetails.getPassword())) {
      return new UsernamePasswordToken(userDetails, true);
    }
    throw new AuthorizationException(AuthorizationErrorCode.AUTHENTICATION_FAILED);

  }

  @Override
  public boolean supports(Map<String, Object> param) {
    String username = "";
    if (param.get(USERNAME_KEY) != null) {
      username = param.get(USERNAME_KEY) + "";
    }
    String password = "";
    if (param.get(PASSWORD_KEY) != null) {
      password = param.get(PASSWORD_KEY) + "";
    }
    return StringUtils.hasText(username) && StringUtils.hasText(password);
  }


}
